/*
 * ConsoleModeBase.cpp
 *
 *  Created on: 16/12/2011
 *      Author: Tales
 */

#include "ConsoleModeBase.hpp"
#include "DrawMode.hpp"
#include "../controller.hpp"
#include <SDL_ttf.h>
#include "../Graphics.hpp"

namespace yep
{
static TTF_Font * font = NULL;
static size_t frameCount = 0;
static const size_t cursorTime = 20;

ConsoleModeBase::ConsoleModeBase()
{
	function = NO_FUNCTION;
}

ConsoleModeBase::~ConsoleModeBase()
{
}

void ConsoleModeBase::handle(Editor & editor, const SDL_Event & event)
{
	if (event.type == SDL_KEYDOWN)
	{
		Uint32 sym = event.key.keysym.sym;
		Uint16 uni = event.key.keysym.unicode;

		switch (function)
		{
		case PAUSE:
			function = NO_FUNCTION;
			break;
		case INPUT_INT:
			if (isdigit(uni))
			{
				answer += char(uni);
			}
			else if (sym == SDLK_BACKSPACE)
			{
				if (answer.size() > 0)
					answer.erase(answer.end() - 1);
			}
			else if (sym == SDLK_RETURN || sym == SDLK_KP_ENTER)
			{
				handleAnswer(editor, answer);
				function = NO_FUNCTION;
				lines.back() += answer;
			}
			break;
		case INPUT_YESNO:
			if (sym == SDLK_y || sym == SDLK_s || sym == SDLK_n)
			{
				answer = char(sym);
			}
			else if (sym == SDLK_RETURN || sym == SDLK_KP_ENTER)
			{
				if (answer == "s" || answer == "y")
					handleAnswer(editor, "yes");
				else if (answer == "n")
					handleAnswer(editor, "no");
				function = NO_FUNCTION;
				lines.back() += answer;
			}
			break;
		case INPUT_CHAR:
			if (isprint(uni))
			{
				answer = char(uni);
			}
			else if (sym == SDLK_BACKSPACE)
			{
				if (answer.size() > 0)
					answer.erase(answer.end() - 1);
			}
			else if (sym == SDLK_RETURN || sym == SDLK_KP_ENTER)
			{
				handleAnswer(editor, answer);
				function = NO_FUNCTION;
				lines.back() += answer;
			}
			break;
		default:
			break;
		}
	}
}

void ConsoleModeBase::logic(Editor & editor)
{
	while (function == NO_FUNCTION)
	{
		pair<string, Function> line = getNextLine(editor);
		lines.push_back(line.first);
		function = line.second;
		switch (function)
		{
		case NO_FUNCTION:
			break;
		case END:
			lines.clear();
			Mode::setCurrentMode(DrawMode::getInstance());
			return;
		default:
			answer = "";
			break;
		}
	}
}

void ConsoleModeBase::setup()
{
	function = NO_FUNCTION;
}

void ConsoleModeBase::draw(Editor & editor, SDL_Surface *surface)
{
	if (!font)
	{
		font = TTF_OpenFont("VeraMono.ttf", 14);
		YEP_ERROR_TEST(font, "Can't load the font on console modes");
		YEP_ERROR_TEST(TTF_FontFaceIsFixedWidth(font), "The font isn't fixed width");
	}
	editor.render(surface);

	Graphics g(surface);
	g.setColor(Color(0x33, 0x33,0x33,0x10));
	g.fillRectangle(make_pair(0,0), make_pair(surface->w, surface->h));
//	boxColor(surface, 0, 0, surface->w, surface->h, 0x3333337F);
	Sint16 y = 0;
	for (auto it = lines.begin(); it != lines.end(); ++it)
	{
		SDL_Surface* txt = TTF_RenderUTF8_Blended(font, it->c_str(), SDL_Color{ 0xDf, 0xDf, 0xDf });
		SDL_Rect rect
		{ 0, y };
		SDL_BlitSurface(txt, NULL, surface, &rect);
		y += TTF_FontHeight(font);
	}
	if (lines.size())
	{
		frameCount++;
		bool showCursor = (frameCount / cursorTime) % 2;
		y = y - TTF_FontHeight(font);
		int x = 8 * lines.back().size();
		TTF_SizeUTF8(font, lines.back().c_str(), &x, NULL);

		SDL_Surface* txt = TTF_RenderUTF8_Blended(font, (answer + (showCursor?'_':' ')).c_str(), SDL_Color{ 0x0, 0xDf, 0x0 });
		SDL_Rect rect{ (Sint16) x, y };
		SDL_BlitSurface(txt, NULL, surface, &rect);
	}
}

} /* namespace yep */
